package org.example.oauth2.config;

import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import org.example.oauth2.constant.AuthConstant;
import org.example.oauth2.granter.TdiiTokenGranter;
import org.example.oauth2.service.TdiiClientDetailsServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;

import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.TokenGranter;
import org.springframework.security.oauth2.provider.token.TokenStore;

import javax.sql.DataSource;

/**
 * @program: rabbitmq-study
 * @description:
 * @Version V1.0.0
 * @author: dazhi
 * @create: 2022-02-10 13:41
 **/

@Order
@Configuration
@AllArgsConstructor
@EnableAuthorizationServer
public class OAuth2ServerConfiguration extends AuthorizationServerConfigurerAdapter {
    //springSecurity 向外提供的用于认证的API集合


    private  final DataSource dataSource;

    private  final AuthenticationManager authenticationManager;

    private  final UserDetailsService userDetailsService ;

    private  final ClientDetailsService clientDetailsService;

    private  final TokenStore tokenStore;



    @Override
    @SneakyThrows
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        TdiiClientDetailsServiceImpl clientDetailsService = new TdiiClientDetailsServiceImpl(dataSource);
        clientDetailsService.setSelectClientDetailsSql(AuthConstant.DEFAULT_SELECT_STATEMENT);
        clientDetailsService.setFindClientDetailsSql(AuthConstant.DEFAULT_FIND_STATEMENT);
        clients.withClientDetails(clientDetailsService);

    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) {

        TokenGranter tokenGranter = TdiiTokenGranter.getTokenGranter(authenticationManager, endpoints);

        //配置端点
        endpoints.tokenStore(tokenStore)
                .authenticationManager(authenticationManager)
                .userDetailsService(userDetailsService)
                .tokenGranter(tokenGranter);
    }


    @Override
    public void configure(AuthorizationServerSecurityConfigurer oauthServer) {
        oauthServer
                .allowFormAuthenticationForClients()
                .tokenKeyAccess("permitAll()")
                .checkTokenAccess("isAuthenticated()");
    }
}
